﻿namespace DCHealthCheck.DomainModel {

    #region Usings
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    #endregion

    [Table("HealthCheckSummary")]
    public class HealthCheckSummary : IHealthCheckSummary, IObjectWithState, IValidatableObject {

        #region Members
        [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
        public virtual DateTime CheckDateUTC { get; set; }

        public virtual DateTime CheckDateTimeUTC { get; set; }

        public virtual int DCsTested {
            get {
                if ((this.SystemInfos != null) && (this.SystemInfos.Count > 0)) {
                    return this.SystemInfos.Count;
                }

                return dcsTested;
            }
            set { dcsTested = value; }
        }
        private int dcsTested;

        public virtual int DCsWithErrors {
            get {
                if ((this.SystemInfos != null) && (this.SystemInfos.Count > 0)) {
                    return this.SystemInfos.Where(x => !string.IsNullOrWhiteSpace(x.ErrorMessage)).Count();
                }

                return dcsWithErrors;
            }
            set { dcsWithErrors = value; }
        }
        private int dcsWithErrors;

        public virtual int Id { get; set; }

        public virtual string Summary { get; set; }

        public virtual ICollection<SystemInfo> SystemInfos {
            get {
                if (systemInfos == null) systemInfos = new List<SystemInfo>();
                return systemInfos;
            }
            set { systemInfos = value; }
        }
        private ICollection<SystemInfo> systemInfos; 

        #region NotMapped properties
        [NotMapped]
        public Object EntityKey { get { return this.Id; } }

        [NotMapped]
        public Dictionary<string, object> StartingOriginalValues { get; set; }

        [NotMapped]
        public DetachedState DetachedState { get; set; }
        #endregion
        #endregion

        #region Constructor
        public HealthCheckSummary() {
            this.Summary = string.Empty;
        } 
        #endregion

        #region Methods
        [DebuggerStepThroughAttribute]
        public override string ToString() {
            var info = new StringBuilder();
            info.Append(string.Format("Date: {0}; ", this.CheckDateTimeUTC.ToString("yyyy-MMM-dd HH:mm")));
            info.Append(string.Format("DC's Tested: {0}; ", this.DCsTested));
            info.Append(string.Format("DC's with Errors: {0}", this.DCsWithErrors));

            return info.ToString();
        }

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
            if (this.CheckDateTimeUTC == DateTime.MinValue) {
                yield return new ValidationResult(
                    "CheckDateTimeUTC is required.", new[] { "CheckDateTimeUTC" });
            }

            if (!this.SystemInfos.ToList().All(x => x.CheckDateTimeUTC == this.CheckDateTimeUTC)) {
                yield return new ValidationResult(
                    "All SystemInfos CheckDateTimeUTC must match.", new[] { "SystemInfos" });
            }

            if (string.IsNullOrWhiteSpace(this.Summary)) {
                yield return new ValidationResult(
                    "Summary is required.", new[] { "Summary" });
            }
        } 
        #endregion
    }
}
